package Lib3d.SceneGraph.Impl;


import Lib3d.Draw;
import Lib3d.Material;
import Lib3d.MaterialLib;
import Lib3d.Object3d;
import Lib3d.Loader.ObjLoader;
import Lib3d.MyUtils.BoundingBox;
import Lib3d.MyUtils.Debug;
import Lib3d.MyUtils.MaterialLibSingleton;
import Lib3d.SceneGraph.Geometry;
import Lib3d.SceneGraph.ObjectNode;

import java.io.IOException;
import java.util.Vector;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;

/**
 * An object node implementation of the scene graph.
 * 
 * @author Wassim Chegham
 * @version 0.1
 * @category Lib3d.SceneGraphImpl
 * 
 */
public class ObjectNodeImpl implements ObjectNode {

    protected Geometry geometry;
    protected MaterialLib mat_lib = MaterialLibSingleton.getInstance();

    public ObjectNodeImpl() {}

    public void addGeometry(final Geometry geometry) {
        this.geometry = geometry;
    }

    public void addMaterial(final Material material) {
        try {
            ObjLoader.load(material.getIdentifier(), this.mat_lib);
            this.mat_lib.addMaterial(material);
        }
        catch (final IOException e) {
            e.printStackTrace();
        }
    }

    public void draw(final GLAutoDrawable gLDrawable) {
        final GL gl = gLDrawable.getGL();
        if (this.geometry != null) {
            final Vector<Object3d> o = this.geometry.getObjects();

            for (int cpt = 0; cpt < o.size(); ++cpt) {
                Draw.draw(gLDrawable, o.get(cpt), this.mat_lib);
            }

            this.drawBB(o, gLDrawable);

        }
    }

    public void drawBB(final Vector<Object3d> o, final GLAutoDrawable gLDrawable) {
        final GL gl = gLDrawable.getGL();
        BoundingBox bbox;
        float r, g, b;
        if (Debug.showGlobalBBox) {
            bbox = new BoundingBox(o);
            if (bbox.interset(bbox)) {
                r = 255f;
                g = 0;
                b = 0;
            }
            else {
                r = 0;
                g = 0;
                b = 0;
            }
            gl.glEnable(GL.GL_COLOR_MATERIAL);
            gl.glColor3f(r, g, b);
            bbox.drawComponentBBox(gLDrawable);
            gl.glDisable(GL.GL_COLOR_MATERIAL);
        }
        if (Debug.showSingleBBox) {
            Object3d oo;
            for (int cpt = 0; cpt < o.size(); ++cpt) {
                oo = o.get(cpt);
                bbox = new BoundingBox(oo);
                if (bbox.interset(bbox)) {
                    r = 255f;
                    g = 0;
                    b = 0;
                }
                else {
                    r = 0;
                    g = 0;
                    b = 0;
                }
                gl.glEnable(GL.GL_COLOR_MATERIAL);
                gl.glColor3f(r, g, b);
                bbox.drawComponentBBox(gLDrawable);
                gl.glDisable(GL.GL_COLOR_MATERIAL);
            }
        }
    }

    public Geometry getGeometry() {
        return this.geometry;
    }

    public MaterialLib getMaterial() {
        return this.mat_lib;
    }

}
